﻿#include "../HDCManager.h"
#include "../include/HSettingConfigOperator.h"
#include "../HCustomWidgets/HMessagePanel.h"
#include "../include/HResolutionConfigResolver.h"

int HDCManager::m_nLoginResult = -1;

HDCManager::HDCManager(QObject *parent)
    :QObject(parent)
{
	qRegisterMetaType<HTTreeItemInfo>("HTTreeItemInfo");
    m_nLoginResult = -1;
    AVCLIENT_RegisterVideoCallBackFun(CallBackResult, this);
    //init();
	HResolutionConfigResolver::dealResolutionConfigInfo(QApplication::applicationDirPath() + XMLRELATIONPATH + "resolutionConfig/mainConfig.xml");
	connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(sltAppToQuit()));
	connect(this,SIGNAL(sigDealWarningInfo(int)),this,SLOT(sltDealWarningInfo(int)));
}


HDCManager::~HDCManager()
{

}

void HDCManager::CallBackResult(DataStructType eType, void *pResultData, void *pThis)
{
    switch(eType)
        {
        case ETYPE_BASE_RESULT:
            {
                BaseResult* pResult = (BaseResult*)(pResultData);
                //m_nResult = pResult->result;
				//int nResult = pResult->result;
            }
            break;
        case ETYPE_LOGIN_RESULT:
            {
                LoginResult* pResult = (LoginResult*)(pResultData);
				if(pResult)
				{
					m_nLoginResult = pResult->result;
					HDCManager *pManager = (HDCManager*)(pThis);
					pManager->dealLoginResult(pResult);
					//增加打开客户端恢复场景时，打开上一次打开的媒体流
					pManager->initRecoveryScenesOpenVideo();
				}
            }
            break;
        case ETYPE_BROADCAST_RESULT:
            {
                BroadcastResult* pResult = (BroadcastResult*)(pResultData);
				if(pResult)
				{
					int nResult = pResult->result;
					int tastID = pResult->taskId;

					HDCManager *pManager = (HDCManager*)(pThis);
					if(pManager->m_pDCPanelInterface)
					{
						if(nResult == 101)
						{
							HMessagePanel *message = new HMessagePanel(NULL);
							message->show();
						}

						pManager->m_pDCPanelInterface->setTaskID(tastID);

					}
					// HVideoWindow* pWindow = (HVideoWindow*)(pThis);
					// pWindow->SetBroadcastResult(*pResult);
				}
				
            }
		case ETYPE_EXTRA_RESULT:
			{
				ExtraResult* pResult = (ExtraResult*)(pResultData);
				if(pResult)
				{
					int nDeviceID = pResult->deviceID;
					QString strResolution = QString::fromStdString(pResult->extraValue);
					QStringList sltResolution = strResolution.split(":");
					if(sltResolution.count() == 4)
					{
						HDCManager *pManager = (HDCManager*)(pThis);
						if(pManager->m_pDCPanelInterface)
						{
							QString strResultResolution = sltResolution.at(1) + " X " + sltResolution.at(3);
							pManager->m_pDCPanelInterface->setPanelResolution(nDeviceID,strResultResolution);
						}
					}
				}				
			    break;
			}
		case ETYPE_NVRChannle_RESULT:
			{
				std::vector<UserDeviceItem> *userDevice = (std::vector<UserDeviceItem>*)(pResultData);

				HDCManager *pManager = (HDCManager*)(pThis);
				pManager->dealAppendTreeItem(userDevice);
				break;
			}
        case ETYPE_EventMessage_RESULT:
            {
                int * t_pnDeviceId = (int*)(pResultData);

				int nDeviceId = *t_pnDeviceId;

                HDCManager *pManager = (HDCManager*)(pThis);
                pManager->dealWarningInfo(nDeviceId);

                break;
            }
        default:
            break;
        }
}


void HDCManager::init(bool bAuto,QStringList lstArgs)
{
    m_pLoginInterface = NULL;
    m_pdcViewLoginPanel = NULL;

    m_pDCPanelInterface = NULL;
    m_pDomeControlPanel = NULL;

	loadLoginUI(lstArgs);
	loadDomeControlPanel();

	if(bAuto)
	{
		m_pdcViewLoginPanel->hide();

		if(lstArgs.count() > 1)
		{
			HTUIProtocol uiProtocol;
			uiProtocol.m_mainType = UIPM_Login;
			uiProtocol.m_hashProperty.insert(HEP_USERNAME,QVariant(lstArgs[0]));
			uiProtocol.m_hashProperty.insert(HEP_PASSWORD,QVariant(lstArgs[1]));
			sltDealViewInfo(uiProtocol);
		}
	}
	else
	{
		m_pdcViewLoginPanel->show();
	}   
}

void HDCManager::initRecoveryScenesOpenVideo()
{
	m_pDCPanelInterface->iniWidget();
}

void HDCManager::loadLoginUI(QStringList strLstLoginInfo)
{
     QPluginLoader loader(g_strAppPath + PLUGINRELATIONPATH + "HLoginPanel.dll");
     if(loader.load())
     {
         m_pLoginInterface = dynamic_cast<HLoginInterface*>(loader.instance());
         m_pLoginInterface->setAppPath(g_strAppPath);
         if(m_pLoginInterface)
         {
             m_pdcViewLoginPanel = m_pLoginInterface->createWidget();
             connect(m_pdcViewLoginPanel,SIGNAL(sigSendUIProtocol(HTUIProtocol)),this,SLOT(sltDealViewInfo(HTUIProtocol)));
         }
		 m_pLoginInterface->setLoginInfo(strLstLoginInfo);
     }

	 QString strloadError = loader.errorString();
}


void HDCManager::loadDomeControlPanel()
{
    QPluginLoader loader(g_strAppPath + PLUGINRELATIONPATH + "HDomeControlPanel.dll");
    if(loader.load())
    {
        m_pDCPanelInterface = dynamic_cast<HDomeControlPanelInterface*>(loader.instance());
        m_pDCPanelInterface->setAppPath(g_strAppPath);
        if(m_pDCPanelInterface)
        {
            m_pDomeControlPanel = m_pDCPanelInterface->createWidget();
            connect(m_pDomeControlPanel,SIGNAL(sigSendUIProtocol(HTUIProtocol)),this,SLOT(sltDealViewInfo(HTUIProtocol)));
        }
    }
}

void HDCManager::dealLoginResult(LoginResult *loginResult)
{
    int nResult = loginResult->result;
    if (nResult == 0)
    {
        QList<HTTreeItemInfo*> lstTreeItemInfoTemp;
        QList<HTTreeItemInfo*> lstTreeItemInfoResult;
        QMultiHash<int,HTTreeItemInfo*> hashMasterIDToItemInfo;

		std::vector<AVRelationItem> t_avRelation = loginResult->avRelation;
        /*Fill List Device Group Item*/

        for (int i = 0; i < loginResult->deviceGroup.size(); i++)
        {
            int id = loginResult->deviceGroup[i].id;
            int masterId = loginResult->deviceGroup[i].masterId;
            QString name = QString::fromLocal8Bit( loginResult->deviceGroup[i].name.c_str() );

            HTTreeItemInfo *itemInfo = new HTTreeItemInfo();
            itemInfo->m_bOnline = true;
            itemInfo->m_strItemText = name;
			itemInfo->m_bIsGroup = true;
            //itemInfo->m_varData = QVariant(id);
			itemInfo->m_hashIDToData.insert(VIDEO,QVariant(id));
            lstTreeItemInfoTemp.append(itemInfo);
            hashMasterIDToItemInfo.insertMulti(masterId,itemInfo);
			if(masterId == 0)
			{
				lstTreeItemInfoResult.append(itemInfo);
			}
        }
        /*Fill List User Device Item*/
        for (int j = 0; j < loginResult->userDevice.size(); j++)
        {
            int id = loginResult->userDevice[j].id;
            int masterId = loginResult->userDevice[j].groupId;
            QString name = QString::fromLocal8Bit( loginResult->userDevice[j].name.c_str() );

            HTTreeItemInfo *itemInfo = new HTTreeItemInfo();
            itemInfo->m_bOnline = true;
			itemInfo->m_bIsGroup = false;
            itemInfo->m_strItemText = name;
            //itemInfo->m_varData = QVariant(id);
			itemInfo->m_hashIDToData.insert(VIDEO,QVariant(id));
			itemInfo->m_hashIDToData.insert(BITSTREAM,QVariant(loginResult->userDevice[j].StreamType));
			for(int AudioRelationIndex = 0; AudioRelationIndex < t_avRelation.size(); AudioRelationIndex ++)
			{
				AVRelationItem relationItem = t_avRelation.at(AudioRelationIndex);
				if(relationItem.videoDeviceId == id)
				{
					QList<QVariant> lstAudioID;
					for(int audioIndex = 0; audioIndex < relationItem.lstAudioDeviceId.size(); audioIndex ++)
					{
						int audioID = relationItem.lstAudioDeviceId.at(audioIndex);
						lstAudioID.append(QVariant(audioID));
					}
					itemInfo->m_hashIDToData.insert(AUDIO,QVariant(lstAudioID));
					break;
				}
			}
            //lstTreeItemInfoTemp.append(itemInfo);
            hashMasterIDToItemInfo.insertMulti(masterId,itemInfo);
			if(masterId == 0)
			{
				lstTreeItemInfoResult.append(itemInfo);
			}
        }

        for(int itemInfoIndex = 0; itemInfoIndex < lstTreeItemInfoTemp.count(); itemInfoIndex++)
        {
			bool bTHasDouble = false;
            HTTreeItemInfo *currentItemInfo = lstTreeItemInfoTemp.at(itemInfoIndex);

            QList<HTTreeItemInfo*> lstChildItemInfo = hashMasterIDToItemInfo.values(currentItemInfo->m_hashIDToData.value(VIDEO).toInt());
			////确保所给数据子节点中没有自己，避免此种情况引起的死循环嵌套。
			//for(int chileItemInfoIndex = 0; chileItemInfoIndex < lstChildItemInfo.count();chileItemInfoIndex ++)
			//{
			//	int nTempID = lstChildItemInfo.at(chileItemInfoIndex)->m_hashIDToData.value(VIDEO).toInt();
			//	int nCurrentID = currentItemInfo->m_hashIDToData.value(VIDEO).toInt();

			//	if(nTempID == nCurrentID)
			//	{
   //                 bTHasDouble = true;
			//		break;
			//	}
			//}
			//if(!bTHasDouble)
			{
				currentItemInfo->m_lstChildItems = lstChildItemInfo;
			}            
        }

        if(m_pDCPanelInterface)
        {
            m_pDCPanelInterface->updateTreeUI(lstTreeItemInfoResult);
        }
		if(m_pLoginInterface)
		{
			m_pLoginInterface->setWarning("");
		}

        //m_pdcViewLoginPanel->close();
        if (m_pdcViewLoginPanel != NULL)
        {
			m_pdcViewLoginPanel->hide();
			//m_pdcViewLoginPanel
            //delete m_pdcViewLoginPanel;
            //m_pdcViewLoginPanel = NULL;
        }

        if(m_pDomeControlPanel)
        {
            m_pDomeControlPanel->showMaximized();
            m_pDomeControlPanel->raise();
        }
    }
	else if(loginResult->result == -1)
	{
		if(!m_pdcViewLoginPanel->isVisible())
		{
			m_pdcViewLoginPanel->show();
			m_pdcViewLoginPanel->raise();
		}

		int nErrorResult = AVCLIENT_GetLastError();
		switch(nErrorResult)
		{
		case 3:
			{
				m_pLoginInterface->setWarning(QString::fromLocal8Bit(WARNINGSTR_ARG));
				break;
			}
		case 4:
			{
				m_pLoginInterface->setWarning(QString::fromLocal8Bit(WARNINGSTR_USERNAMEANDPASS));
				break;
			}
		default:
			{
				break;
			}
		}
	}
}

void HDCManager::dealAppendTreeItem(std::vector<UserDeviceItem> *deviceItem)
{
	int nGroupID = 0;
	QList<HTTreeItemInfo*> lstTreeItemInfos;
	for(int i = 0; i < deviceItem->size(); i++)
	{
		UserDeviceItem deviceItemChild = deviceItem->at(i);

		nGroupID = deviceItemChild.groupId;

		HTTreeItemInfo *itemInfo = new HTTreeItemInfo();
		itemInfo->m_bOnline = true;
		itemInfo->m_bIsGroup = false;
		itemInfo->m_strItemText = QString::fromLocal8Bit(deviceItemChild.name.c_str());
		//itemInfo->m_varData = QVariant(id);
		itemInfo->m_hashIDToData.insert(VIDEO,QVariant(deviceItemChild.id));
		itemInfo->m_hashIDToData.insert(BITSTREAM,QVariant(deviceItemChild.StreamType));

		lstTreeItemInfos.append(itemInfo);
	}

	HTTreeItemInfo *itemInfoParent = new HTTreeItemInfo();
	itemInfoParent->m_bOnline = true;
	itemInfoParent->m_bIsGroup = false;
	itemInfoParent->m_strItemText = "";
	//itemInfo->m_varData = QVariant(id);
	itemInfoParent->m_hashIDToData.insert(VIDEO,QVariant(nGroupID));
	itemInfoParent->m_lstChildItems = lstTreeItemInfos;

	if(m_pDCPanelInterface)
	{
		m_pDCPanelInterface->appendTreeItem(itemInfoParent);
    }
}

void HDCManager::dealWarningInfo(int nDeviceID)
{
	emit sigDealWarningInfo(nDeviceID);
}

void HDCManager::sltDealViewInfo(HTUIProtocol uiProtocol)
{
    switch (uiProtocol.m_mainType) {
    case UIPM_Login:
    {
        //QList<HEPropertyName> propertyName = uiProtocol.m_hashProperty.keys();
        QString strUserName = uiProtocol.m_hashProperty.value(HEP_USERNAME).toString();
        QString strPassword = uiProtocol.m_hashProperty.value(HEP_PASSWORD).toString();

		bool t = HSettingConfigOperator::readConfig(m_hashSetting,g_strAppPath + XMLRELATIONPATH + "settingConfig.xml");

		/*QByteArray serverByte = m_hashSetting.value("serverIP").toLocal8Bit();
		char *serverChar = serverByte.data();*/
		QString serverIp = m_hashSetting.value("serverIP");
		QString ServerPort = m_hashSetting.value("serverPort");
		QString resUrl =  m_hashSetting.value("resUrl");

		//QString LocalSipid = m_hashSetting.value("sipFrom");
		
		QString strGuidResult;
		GUID guid;
        if(CoCreateGuid(&guid) == S_OK)
		{
			char buf[64] = {0};
			{
				_snprintf(buf, sizeof(buf), "%08X-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X", 
					guid.Data1,
					guid.Data2,
					guid.Data3,
					guid.Data4[0],
					guid.Data4[1],
					guid.Data4[2],
					guid.Data4[3],
					guid.Data4[4],
					guid.Data4[5],
					guid.Data4[6],
					guid.Data4[7]);
			}
			strGuidResult =  buf;
		}
		QString LocalSipid = QString("DV_pc_") + strGuidResult;

		QString LocalDomain = m_hashSetting.value("sipArea");
		QString ToSipid = m_hashSetting.value("sipTo");
        
		AVCLIENT_SetExtraParamBeforeLogin(serverIp.toLocal8Bit().data(), ServerPort.toLocal8Bit().data(), LocalSipid.toLocal8Bit().data(), LocalDomain.toLocal8Bit().data(), ToSipid.toLocal8Bit().data(),resUrl.toLocal8Bit().data());
		//AVCLIENT_Temp_Login(strUserName.toLocal8Bit().data(), strPassword.toLocal8Bit().data());
		AVCLIENT_Login(strUserName.toLocal8Bit().data(), strPassword.toLocal8Bit().data());
    }

        break;
	case UIPM_Setting:
		{
			
			break;
		}
	case UIPM_DeviceSelect:
		{
			switch(uiProtocol.m_subType)
			{
			case UIPS_OPENVIDEO:
				{
					QVariant varHandle = uiProtocol.m_hashProperty.value(HEP_VEDIOHANDLE);
					QWidget *t_pwndVideoLabel = NULL;
					if (varHandle.canConvert<QWidget*>())
					{
						t_pwndVideoLabel = varHandle.value<QWidget*>();
					}

					QVariant varVideoID = uiProtocol.m_hashProperty.value(HEP_DEVIDEID);
					QVariant varBitStream = uiProtocol.m_hashProperty.value(HEP_BITSTREAM); 
					AVCLIENT_PlayVideo((HWND)t_pwndVideoLabel->winId(),varVideoID.toInt(),varBitStream.toString().toStdString());
					break;
				}
			case UIPS_CLOSEVIDEO:
				{
					QVariant varVideoID = uiProtocol.m_hashProperty.value(HEP_DEVIDEID);
					QVariant varBitStream=uiProtocol.m_hashProperty.value(HEP_BITSTREAM);
					AVCLIENT_StopVideo(varVideoID.toInt(),varBitStream.toString().toStdString());
                    break;
				}
			case UIPS_OPENBROADCAST:
				{
					QVariant varVideoID = uiProtocol.m_hashProperty.value(HEP_DEVIDEID);
					std::vector<int> audioDeviceIDs;
					audioDeviceIDs.push_back(varVideoID.toInt());
					AVCLIENT_StartBroadcast(audioDeviceIDs);
					break;
				}
			case UIPS_CLOSEBROADCAST:
				{
					QVariant varTaskID = uiProtocol.m_hashProperty.value(HEP_TASKID);
					AVCLIENT_StopBroadcast(varTaskID.toInt());
					break;
				}
			case UIPS_CHECKDEVICEGROUP:
				{
					QVariant varVideoID = uiProtocol.m_hashProperty.value(HEP_DEVIDEID);
					AVCLIENT_GetSubChannle(varVideoID.toInt());
					break;
				}
			case UIPS_ADDALARMVIDEO :
				{
					QVariant varHandle = uiProtocol.m_hashProperty.value(HEP_VEDIOHANDLE);
					QWidget *t_pwndVideoLabel = NULL;
					if (varHandle.canConvert<QWidget*>())
					{
						t_pwndVideoLabel = varHandle.value<QWidget*>();
					}

					QVariant varVideoID = uiProtocol.m_hashProperty.value(HEP_DEVIDEID);
					QVariant varBitStream = uiProtocol.m_hashProperty.value(HEP_BITSTREAM); 
					AVCLIENT_AddAlarmVideo((HWND)t_pwndVideoLabel->winId(),varVideoID.toInt(),varBitStream.toString().toStdString());
					break;
				}


			case UIPS_DELALARMVIDEO	:
				{
					QVariant varVideoID = uiProtocol.m_hashProperty.value(HEP_DEVIDEID);
					QVariant varBitStream=uiProtocol.m_hashProperty.value(HEP_BITSTREAM);
					AVCLIENT_DelAlarmVideo(varVideoID.toInt(),varBitStream.toString().toStdString());
					break;
				}
			case UIPS_PAUSSEVIDEO :
				{
					QVariant varVideoID = uiProtocol.m_hashProperty.value(HEP_DEVIDEID);
					AVCLIENT_PauseVideo(varVideoID.toInt());
					break;
				}
			case UIPS_CONTINUEVIDEO :
				{
					QVariant varVideoID = uiProtocol.m_hashProperty.value(HEP_DEVIDEID);
					AVCLIENT_ContinueVideo(varVideoID.toInt());
					break;
				}


			default:
				break;
			}
			break;
		}
    case UIPM_DeviceControl:
    {
        switch (uiProtocol.m_subType) {
        case UIPS_DOMEBTNCLICKED:
        {
            QVariant varBtnPosition = uiProtocol.m_hashProperty.value(HEP_DOMEBTNPOSITION);
            QVariant varBtnType = uiProtocol.m_hashProperty.value(HEP_DOMEBTNTYPE);
            QVariant varCurrentVideoID = uiProtocol.m_hashProperty.value(HEP_DEVIDEID);
            QVariant varControlSpeed = uiProtocol.m_hashProperty.value(HEP_CONTROLSPEED);

            int nBtnPosition = varBtnPosition.toInt();
            int nBtnType = varBtnType.toInt();

            PTZType     StructPTZ_TYPE;
            switch (nBtnPosition) {
            case 1:
                StructPTZ_TYPE = CONTROL_TOP_MIDDLE;
                break;
            case 2:
                StructPTZ_TYPE = CONTROL_BOTTOM_MIDDLE;
                break;
            case 3:
                StructPTZ_TYPE = CONTROL_MID_LEFT;
                break;
            case 4:
                StructPTZ_TYPE = CONTROL_MID_RIGHT;
                break;
            case 5:
                StructPTZ_TYPE = CONTROL_TOP_LEFT;
                break;
            case 6:
                StructPTZ_TYPE = CONTROL_TOP_RIGHT;
                break;
            case 7:
                StructPTZ_TYPE = CONTROL_BOTTOM_LEFT;
                break;
            case 8:
                StructPTZ_TYPE = CONTROL_BOTTOM_RIGHT;
                break;
            case 9:
                StructPTZ_TYPE = CONTROL_MID_MIDDLE;
                break;
            case 10:
                StructPTZ_TYPE = CONTROL_ZOOMIN;
                break;
            case 11:
                StructPTZ_TYPE = CONTROL_ZOOMOUT;
                break;
            case 12:
                StructPTZ_TYPE = CONTROL_FOCUSNEAR;
                break;
            case 13:
                StructPTZ_TYPE = CONTROL_FOCUSFAR;
                break;
            case 14:
                StructPTZ_TYPE = CONTROL_IRISENLARGE;
                break;
            case 15:
                StructPTZ_TYPE = CONTROL_IRISSHRINK;
                break;
			default:
				return;
            }

            bool bOpen = false;
            if (nBtnType == 1)
            {
                bOpen = true;
            }

            if(m_nLoginResult == 0)
            {
                AVCLIENT_PTZControl(varCurrentVideoID.toInt(), StructPTZ_TYPE, bOpen, 1, varControlSpeed.toInt());
            }
            else
            {

            }
        }
            break;
        default:
            break;
        }
        break;
    }
    default:
        break;
    }
}

void HDCManager::sltAppToQuit()
{
	AVCLIENT_Logout();
	if(m_pdcViewLoginPanel)
	{
		m_pdcViewLoginPanel->setParent(NULL);
		delete m_pdcViewLoginPanel;
		m_pdcViewLoginPanel = NULL;
	}

	if(m_pDomeControlPanel)
	{
		m_pDomeControlPanel->setParent(NULL);
		delete m_pDomeControlPanel;
		m_pDomeControlPanel = NULL;
	}

	if(m_pDCPanelInterface)
	{
		m_pDCPanelInterface->setParent(NULL);
		delete m_pDCPanelInterface;
		m_pDCPanelInterface = NULL;
	}

	if(m_pLoginInterface)
	{
		m_pLoginInterface->setParent(NULL);
		delete m_pLoginInterface;
		m_pLoginInterface = NULL;
	}
}

void HDCManager::sltDealWarningInfo(int nDeviceID)
{
	if(m_pDCPanelInterface)
	{
		m_pDCPanelInterface->setDeviceWarning(nDeviceID);
	}
}
